home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 223_01 / cc13.c < prev    next >
Text File  |  1980-01-01  |  8KB  |  316 lines

  1.  
  2. /*
  3. ** statement parser
  4. **
  5. ** called whenever syntax requires a statement
  6. **  this routine performs that statement
  7. **  and returns a number telling which one
  8. */
  9. statement() {
  10.   if ((ch==0) & (eof)) return;
  11.   else if(amatch("char",4))  {declloc(CCHAR);ns();}
  12.   else if(amatch("int",3))   {declloc(CINT);ns();}
  13.   else {
  14.     if(declared >= 0) {
  15. #ifdef STGOTO
  16.       if(ncmp > 1) nogo=declared; /* disable goto if any */
  17. #endif
  18.       csp=modstk(csp - declared, NO);
  19.       declared = -1;
  20.       }
  21.     if(match("{"))               compound();
  22.     else if(amatch("if",2))      {doif();lastst=STIF;}
  23.     else if(amatch("while",5))   {dowhile();lastst=STWHILE;}
  24. #ifdef STDO
  25.     else if(amatch("do",2))      {dodo();lastst=STDO;}
  26. #endif
  27. #ifdef STFOR
  28.     else if(amatch("for",3))     {dofor();lastst=STFOR;}
  29. #endif
  30. #ifdef STSWITCH
  31.     else if(amatch("switch",6))  {doswitch();lastst=STSWITCH;}
  32.     else if(amatch("case",4))    {docase();lastst=STCASE;}
  33.     else if(amatch("default",7)) {dodefault();lastst=STDEF;}
  34. #endif
  35. #ifdef STGOTO
  36.     else if(amatch("goto", 4))   {dogoto(); lastst=STGOTO;}
  37.     else if(dolabel())           lastst=STLABEL;     /*55*/
  38. #endif
  39.     else if(amatch("return",6))  {doreturn();ns();lastst=STRETURN;}
  40.     else if(amatch("break",5))   {dobreak();ns();lastst=STBREAK;}
  41.     else if(amatch("continue",8)){docont();ns();lastst=STCONT;}
  42.     else if(match(";"))          errflag=0;
  43.     else if(match("#asm"))       {doasm();lastst=STASM;}
  44.     else                         {doexpr();ns();lastst=STEXPR;}
  45.     }
  46.   return lastst;
  47.   }
  48.  
  49. /*
  50. ** semicolon enforcer
  51. **
  52. ** called whenever syntax requires a semicolon
  53. */
  54. ns()  {
  55.   if(match(";")==0) error("no semicolon");
  56.   else errflag=0;
  57.   }
  58.  
  59. compound()  {
  60.   int savcsp;
  61.   char *savloc;
  62.   savcsp=csp;
  63.   savloc=locptr;
  64.   declared=0;    /* may now declare local variables */
  65.   ++ncmp;        /* new level open */
  66.   while (match("}")==0)
  67.     if(eof) {
  68.       error("no final }");
  69.       break;
  70.       }
  71.     else statement();     /* do one */
  72.   --ncmp;                 /* close current level */
  73. /*55*/
  74. #ifdef STGOTO
  75.   if(lastst != STRETURN && lastst != STGOTO)
  76. #else
  77.   if(lastst != STRETURN)
  78. #endif
  79.     modstk(savcsp, NO); /* delete local variable space */
  80.   csp=savcsp;
  81. /*55*/
  82. #ifdef STGOTO
  83.   cptr=savloc;            /* retain labels */
  84.   while(cptr < locptr) {
  85.     cptr2=nextsym(cptr);
  86.     if(cptr[IDENT] == LABEL) {
  87.       while(cptr < cptr2) *savloc++ = *cptr++;
  88.       }
  89.     else cptr=cptr2;
  90.     }
  91. #endif
  92.   locptr=savloc;          /* delete local symbols */
  93.   declared = -1;          /* may not declare variables */
  94.   }
  95.  
  96. doif()  {
  97.   int flab1,flab2;
  98.   flab1=getlabel(); /* get label for false branch */
  99.   test(flab1, YES); /* get expression, and branch false */
  100.   statement();      /* if true, do a statement */
  101.   if (amatch("else",4)==0) {      /* if...else ? */
  102.     /* simple "if"...print false label */
  103.     postlabel(flab1);
  104.     return;         /* and exit */
  105.     }
  106.   flab2=getlabel();
  107. #ifdef STGOTO
  108.   if((lastst != STRETURN)&(lastst != STGOTO)) jump(flab2);
  109. #else
  110.   if(lastst != STRETURN) jump(flab2);
  111. #endif
  112.   postlabel(flab1); /* print false label */
  113.   statement();      /* and do "else" clause */
  114.   postlabel(flab2); /* print true label */
  115.   }
  116.  
  117. doexpr() {
  118.   int const, val;
  119.   char *before, *start;
  120.   while(1) {
  121.     setstage(&before, &start);
  122.     expression(&const, &val);
  123.     clearstage(before, start);
  124.     if(ch != ',') break;
  125.     bump(1);
  126.     }
  127.   }
  128.  
  129. dowhile()  {
  130.   int wq[4];              /* allocate local queue */
  131.   addwhile(wq);           /* add entry to queue for "break" */
  132.   postlabel(wq[WQLOOP]);  /* loop label */
  133.   test(wq[WQEXIT], YES);  /* see if true */
  134.   statement();            /* if so, do a statement */
  135.   jump(wq[WQLOOP]);       /* loop to label */
  136.   postlabel(wq[WQEXIT]);  /* exit label */
  137.   delwhile();             /* delete queue entry */
  138.   }
  139.  
  140. #ifdef STDO
  141. dodo() {
  142.   int wq[4], top;
  143.   addwhile(wq);
  144.   postlabel(top=getlabel());
  145.   statement();
  146.   needtoken("while");
  147.   postlabel(wq[WQLOOP]);
  148.   test(wq[WQEXIT], YES);
  149.   jump(top);
  150.   postlabel(wq[WQEXIT]);
  151.   delwhile();
  152.   ns();
  153.   }
  154. #endif
  155.  
  156. #ifdef STFOR
  157. dofor() {
  158.   int wq[4], lab1, lab2;
  159.   addwhile(wq);
  160.   lab1=getlabel();
  161.   lab2=getlabel();
  162.   needtoken("(");
  163.   if(match(";")==0) {
  164.     doexpr();            /* expr 1 */
  165.     ns();
  166.     }
  167.   postlabel(lab1);
  168.   if(match(";")==0) {
  169.     test(wq[WQEXIT], NO); /* expr 2 */
  170.     ns();
  171.     }
  172.   jump(lab2);
  173.   postlabel(wq[WQLOOP]);
  174.   if(match(")")==0) {
  175.     doexpr();            /* expr 3 */
  176.     needtoken(")");
  177.     }
  178.   jump(lab1);
  179.   postlabel(lab2);
  180.   statement();
  181.   jump(wq[WQLOOP]);
  182.   postlabel(wq[WQEXIT]);
  183.   delwhile();
  184.   }
  185. #endif
  186.  
  187. #ifdef STSWITCH
  188. doswitch() {
  189.   int wq[4], endlab, swact, swdef, *swnex, *swptr;
  190.   swact=swactive;
  191.   swdef=swdefault;
  192.   swnex=swptr=swnext;
  193.   addwhile(wq);
  194.   *(wqptr + WQLOOP - WQSIZ) = 0;                      /*01*/
  195.   needtoken("(");
  196.   doexpr();      /* evaluate switch expression */
  197.   needtoken(")");
  198.   swdefault=0;
  199.   swactive=1;
  200.   jump(endlab=getlabel());
  201.   statement();   /* cases, etc. */
  202.   jump(wq[WQEXIT]);
  203.   postlabel(endlab);
  204.   sw();          /* match cases */
  205.   while(swptr < swnext) {
  206.     defstorage(CINT>>2);
  207.     printlabel(*swptr++);  /* case label */
  208.     outbyte(',');
  209.     outdec(*swptr++);      /* case value */
  210.     nl();
  211.     }
  212.   defstorage(CINT>>2);
  213.   outdec(0);
  214.   nl();
  215.   if(swdefault) jump(swdefault);
  216.   postlabel(wq[WQEXIT]);
  217.   delwhile();
  218.   swnext=swnex;
  219.   swdefault=swdef;
  220.   swactive=swact;
  221.   }
  222.  
  223. docase() {
  224.   if(swactive==0) error("not in switch");
  225.   if(swnext > swend) {
  226.     error("too many cases");
  227.     return;
  228.     }
  229.   postlabel(*swnext++ = getlabel());
  230.   constexpr(swnext++);
  231.   needtoken(":");
  232.   }
  233.  
  234. dodefault() {
  235.   if(swactive) {
  236.     if(swdefault) error("multiple defaults");
  237.     }
  238.   else error("not in switch");
  239.   needtoken(":");
  240.   postlabel(swdefault=getlabel());
  241.   }
  242. #endif
  243.  
  244. #ifdef STGOTO
  245. dogoto() {
  246.   if(nogo > 0) error("not allowed with block-locals");
  247.   else noloc = 1;
  248.   if(symname(ssname, YES)) jump(addlabel());
  249.   else error("bad label");
  250.   ns();
  251.   }
  252.  
  253. dolabel() {
  254.   char *savelptr;
  255.   blanks();
  256.   savelptr=lptr;
  257.   if(symname(ssname, YES)) {
  258.     if(gch()==':') {
  259.       postlabel(addlabel());
  260.       return 1;
  261.       }
  262.     else bump(savelptr-lptr);
  263.     }
  264.   return 0;
  265.   }
  266.  
  267. addlabel()  {
  268.   if(cptr=findloc(ssname)) {
  269.     if(cptr[IDENT]!=LABEL) error("not a label");
  270.     }
  271.   else cptr=addsym(ssname, LABEL, LABEL, 0, 0, 0, getlabel(), &locptr, LABEL);
  272.                         /* fas 2.3 2.6 */
  273.   return (getint(cptr+OFFSET, OFFSIZE));
  274.   }
  275. #endif
  276.  
  277. doreturn()  {
  278.   if(endst()==0) {
  279.     doexpr();
  280.     modstk(0, YES);
  281.     }
  282.   else modstk(0, NO);
  283.   ffret();
  284.   }
  285.  
  286. dobreak()  {
  287.   int *ptr;
  288.   if ((ptr=readwhile(wqptr))==0) return;            /*01*/
  289.   modstk((ptr[WQSP]), NO);
  290.   jump(ptr[WQEXIT]);
  291.   }
  292.  
  293. docont()  {
  294.   int *ptr;
  295.   ptr = wqptr;                                      /*01*/
  296.   while (1) {                                       /*01*/
  297.     if ((ptr=readwhile(ptr))==0) return;            /*01*/
  298.     if (ptr[WQLOOP]) break;                         /*01*/
  299.     }                                               /*01*/
  300.   modstk((ptr[WQSP]), NO);
  301.   jump(ptr[WQLOOP]);
  302.   }
  303.  
  304. doasm()  {
  305.   ccode=0;                /* mark mode as "asm" */
  306.   while (1) {
  307.     inline();
  308.     if (match("#endasm")) break;
  309.     if(eof)break;
  310.     lout(line, output);                /* fas 2.7 */
  311.     }
  312.   kill();
  313.   ccode=1;
  314.   }
  315.  
  316.